import logging
import os
import pathlib
import sys

import colorlog
from logging.handlers import TimedRotatingFileHandler
from os import path, makedirs
import re

logger = None
# 控制台颜色配置
log_colors_config = {
    'DEBUG': 'white',
    'INFO': 'green',
    'WARNING': 'yellow',
    'ERROR': 'red',
    'CRITICAL': 'bold_red'
}


def get_console_handler():
    console_handler = logging.StreamHandler()
    # 日志级别
    console_handler.setLevel(logging.DEBUG)
    # 日志输出格式
    console_formatter = colorlog.ColoredFormatter(
        fmt='%(log_color)s[%(asctime)s.%(msecs)03d] %(filename)s -> %(funcName)s line:%(lineno)d [%(levelname)s] : %('
            'message)s',
        datefmt='%Y-%m-%d  %H:%M:%S',
        log_colors=log_colors_config
    )
    console_handler.setFormatter(console_formatter)
    return console_handler


def get_file_handler(filename, level_name):
    # 获取日志等级值
    level = getattr(logging, level_name.upper())
    if not isinstance(level, int):
        raise ValueError(f"无效的日志等级: {level_name}")
    if getattr(sys, 'frozen', False):
        # 如果是打包的exe，则获取当前运行目录
        application_path = os.path.dirname(sys.executable)
    else:
        application_path = pathlib.Path(__file__).parent.resolve()
    file_path = path.join(application_path, 'logs', level_name)
    if not path.exists(file_path):
        makedirs(file_path, exist_ok=True)
    file_handler = TimedRotatingFileHandler(
        filename=str(path.join(file_path, f'{filename}_{level_name}.log')),
        when='midnight', interval=1, backupCount=7,
        encoding='utf-8'
    )
    file_handler.setLevel(level)
    file_handler.suffix = '%Y-%m-%d.log'
    file_handler.extMatch = re.compile(r'^\d{4}-\d{2}-\d{2}.log$')
    file_formatter = logging.Formatter(
        fmt='[%(asctime)s.%(msecs)03d] %(filename)s -> %(funcName)s line:%(lineno)d [%(levelname)s] : %(message)s',
        datefmt='%Y-%m-%d  %H:%M:%S'
    )
    file_handler.setFormatter(file_formatter)
    return file_handler


def get_logger(filename='agent'):
    global logger
    if not logger:
        logger = logging.getLogger()
        logger.setLevel(logging.DEBUG)
        if not logger.handlers:
            logger.addHandler(get_console_handler())
            info_handler = get_file_handler(filename=filename, level_name='info')
            error_handler = get_file_handler(filename=filename, level_name='error')
            info_handler.addFilter(lambda record: record.levelno < logging.ERROR)
            error_handler.addFilter(lambda record: record.levelno >= logging.ERROR)
            logger.addHandler(info_handler)
            logger.addHandler(error_handler)
    return logger


get_logger()
